home *** CD-ROM | disk | FTP | other *** search
- /*
- File: CAS_Drag.c
-
- Contains: All the code to handle dragging for the CASample app.
-
- Written by: David H Nelson (from DragText by Rob Johnston)
-
- Copyright © 1993-1995 ComponentWorks, All rights reserved.
-
- Change History (most recent first):
-
- <15> 5/19/93 SJF Kill the check for drop location is finder trash
- because the AECoerceDesc call crashes
- <1> 11/20/93 DHN Created from Scrapbook.c.
-
- */
-
- #include <Folders.h>
-
- #ifdef USE_CALIB
- #include "CALib.h"
- #include "CAS_CAUtil.h"
- #endif
-
- #include "CAS_Globals.h"
- #include "CAS_Drag.h"
- #include "CAS_Misc.h"
- #include "CAS_Doc.h"
- #include "CAS_App.h"
- #include "CAS_StringTools.h"
- #include "CAS_Content.h"
-
- #include <String.h>
-
- //----------------------------------------------------------------------
- // local prototypes
-
- #if defined(__cplusplus)
- extern "C"
- {
- #endif
-
- static short HitTest(Point theLoc, DocPtr theDoc);
- static OSErr GetResFromFile(FSSpec *fileSpec, Handle *h, OSType theType);
- static OSErr GetDataFromFile(FSSpec *fileSpec, Handle *h, long offset, long maxLength);
- static Boolean IsMyTypeAvailable(DragReference theDrag);
- static Boolean DropLocationIsFinderTrash(
- AEDesc *dropLocation );
- static OSErr GetDropFSSpec(DragReference theDrag, FSSpec *dropFSSpec);
-
- #if defined(__cplusplus)
- }
- #endif
-
- #define PROMISES 1
-
-
- //static short insertionOffset, insertionShow, lastOffset, insertPosition;
- static Boolean canAcceptItems;
- static short cursorInContent;
-
- static Boolean localDragInProgress = false;
-
-
- //===========================================================================
- #pragma mark ' CASample Drag Callbacks
- //===========================================================================
-
-
- #ifdef USE_CALIB
-
- pascal OSErr Drag_DragReceiveHandler(
- WindowPtr theWindow,
- void *handlerRefCon,
- DragReference theDrag )
- {
- OSErr theErr;
- OSErr returnErr = dragNotAcceptedErr;
- unsigned short numItems, index;
- DragAttributes attributes;
- short mouseDownModifiers, mouseUpModifiers;
- GrafPtr savePort;
- Point saveOrigin;
- DocPtr theDoc;
- Boolean skipPict = false;
- Point dropMouse, pinnedMouse;
- FSSpec fileSpec;
-
- // if we can't accept the item flavors or the cursor isn't over the item frame,
- // don't accept the drag.
- if (!canAcceptItems || !cursorInContent)
- return dragNotAcceptedErr;
-
- theDoc = (DocPtr)GetWRefCon( theWindow );
-
- GetPort( &savePort );
- SetPort( (GrafPtr)theWindow );
-
- theErr = GetDragAttributes( theDrag, &attributes );
-
- // are we moving the items within our own window?
- if ((attributes & dragInsideSenderWindow) &&
- (localDragInProgress))
- {
- Point startPt, endPt;
-
- // This is where we move the items.
- theErr = GetDragOrigin( theDrag, &startPt );
- theErr = GetDragMouse( theDrag, &endPt, nil );
-
- Doc_MoveSelection( theDoc, endPt.h - startPt.h, endPt.v - startPt.v );
-
- SetPort( savePort );
- return noErr;
- }
-
- theErr = GetDragModifiers( theDrag, 0L, &mouseDownModifiers, &mouseUpModifiers );
- if (theErr != noErr)
- {
- SetPort( savePort );
- return theErr;
- }
-
- theErr = CountDragItems( theDrag, &numItems );
- if (theErr != noErr)
- {
- SetPort( savePort );
- return theErr;
- }
-
- if (numItems <= 0) // if there is nothing to receive…
- {
- SetPort( savePort );
- theErr = dragNotAcceptedErr;
- return theErr;
- }
-
- // turn off the hiliting if needed
- if (attributes & dragHasLeftSenderWindow)
- HideDragHilite( theDrag );
-
- // page = GetCtlValue(theDoc->scrollBar); /* get current page */
-
- // Loop through all of the drag items contained in this drag and add an item for each.
- for (index = 1; index <= numItems; index++)
- {
- ItemReference theItem;
- unsigned short numFlavors;
- unsigned short flavorIndex;
- FlavorType theType;
- Size dataSize;
- FlavorFlags theFlags;
- Handle dataHandle = NULL;
- Rect itemBounds;
- Rect docBounds;
- GrafPtr savePort;
- CADocumentRef dragDropDoc, insertDoc;
- CACloneKind cloneKind;
-
-
- // Get the item's reference number, so we can refer to it.
- // count the number of item flavors.
- theErr = GetDragItemReferenceNumber( theDrag, index, &theItem );
- theErr = CountDragItemFlavors( theDrag, theItem, &numFlavors );
-
- // First Check for our internal type
- if (Drag_DragItemHasFlavor (theDrag, theItem, kCACASScrapType))
- {
- theType = kCACASScrapType;
- dataHandle = Drag_GetFlavorData (theDrag, theItem, kCACASScrapType);
- if (dataHandle == NULL) return dragNotAcceptedErr;
- }
-
- // Now check for flavorTypeHFS
- else if (Drag_DragItemHasFlavor (theDrag, theItem, flavorTypeHFS))
- {
-
- HFSFlavor theHFSFlavor;
-
- dataHandle = Drag_GetFlavorData (theDrag, theItem, flavorTypeHFS);
- if (dataHandle == NULL) return dragNotAcceptedErr;
-
- // save the flavor
- BlockMoveData( *dataHandle, &theHFSFlavor, (long)sizeof(HFSFlavor) );
-
- if (theHFSFlavor.fileType == kPICTType) // PICT file?
- {
-
- theType = kPICTType;
- DisposeHandle( dataHandle ); // throw away the handle, we'll get a new one.
- dataHandle = nil;
-
- // open the data fork and read the pict out of it.
- theErr = GetDataFromFile(&theHFSFlavor.fileSpec, &dataHandle, 512, 0x7FFFFFFF);
-
- }
- else if (theHFSFlavor.fileCreator == 'drag') // CREATOR is Finder clipping file?
- {
- // ignore it since we'll get the clipping flavors also.
- theErr = noErr;
- }
- else if (theHFSFlavor.fileCreator == kODShellSignature)
- {
- theType = kODShellSignature;
- insertDoc = CAOpenDocument (&theHFSFlavor.fileSpec, NULL, 0, 0);
- theErr = CAError();
-
- }
- else if (theHFSFlavor.fileCreator == kOurFileCreator)
- {
- theType = kOurFileCreator;
- BlockMove (&theHFSFlavor.fileSpec, &fileSpec, sizeof (FSSpec));
- }
- else
- // indicate we don't have anything.
- theErr = resNotFound;
-
- }
-
- // If kCAPromiseFlavor is present their is a part in the drag.
- else if (Drag_DragItemHasFlavor (theDrag, theItem, kCAPromiseFlavor))
- {
- theType = kCAPromiseFlavor;
- }
-
- // Last resort kPICTType
- else if (Drag_DragItemHasFlavor (theDrag, theItem, kPICTType))
- {
- theType = kPICTType;
- dataHandle = Drag_GetFlavorData (theDrag, theItem, kPICTType);
- if (dataHandle == NULL) return dragNotAcceptedErr;
-
- }
-
- // Set the port
-
- GetPort( &savePort );
- SetPort( (GrafPtr)Doc_GetWindow( theDoc ) );
-
- // Compute the drop location
-
- // Get the drag region
- GetDragItemBounds( theDrag, theItem, &itemBounds );
-
- // Convert it from global to theDoc local coordinates
-
- OffsetRect( &itemBounds,
- GetControlValue( theDoc->hScrollBar ),
- GetControlValue( theDoc->vScrollBar ) );
-
- dropMouse.v = itemBounds.top;
- dropMouse.h = itemBounds.left;
-
- GlobalToLocal (&dropMouse);
-
- switch (theType)
- {
-
- case kODShellSignature:
-
-
- CAUtil_EmbedODContainerFromCADocument (theDoc, insertDoc, dropMouse);
- CACloseDocument (insertDoc);
- returnErr = noErr;
- break;
-
- case kCACASScrapType:
-
- // Note: This case is not covered since a kCACASScrapType drag
- // is a kCAPromiseFlavor flavor with a part kind of kCACASScrapType
-
- // Get the ODDragDrop object
-
- dragDropDoc = CAGetDragDropDocument(theItem);
- Doc_AddItemsFromCAScrap( theDoc, dataHandle, &dropMouse, dragDropDoc,
- kCACloneDropCopy );
-
- CACloseDocument (dragDropDoc);
- returnErr = noErr;
- break;
-
- case flavorTypeHFS:
-
- returnErr = dragNotAcceptedErr;
- break;
-
- case kPICTType:
- Doc_AddItemPict( theDoc, (PicHandle)dataHandle, dropMouse );
- returnErr = noErr;
- break;
-
- case kCAPromiseFlavor:
- {
-
- CAISOStr partKind;
- dragDropDoc = CAGetDragDropDocument(theItem);
-
- partKind = CAGetDocumentKind (dragDropDoc);
-
- if (bCStrCmp (partKind, kCACASScrapTypeStr))
- {
-
- Handle scrapHandle;
- CASize scrapLength;
-
- CASetOffset (dragDropDoc, 0);
- scrapLength = CAGetSize (dragDropDoc);
-
- scrapHandle = NewHandle (scrapLength);
- CARead (dragDropDoc, *scrapHandle, &scrapLength);
-
- Doc_AddItemsFromCAScrap( theDoc, scrapHandle, &dropMouse, dragDropDoc,
- kCACloneDropCopy );
-
- Win_ShowSelection( Doc_GetWindow( theDoc ) );
- DisposeHandle( scrapHandle );
-
-
- }
- else
- {
- CAUtil_EmbedODContainerFromCADocument (theDoc, dragDropDoc, dropMouse);
- }
-
- DisposePtr (partKind);
- CACloseDocument (dragDropDoc);
- returnErr = noErr;
-
- break;
- }
- case kOurFileCreator:
- {
- // Deselect everything
- Doc_SelectAllElements( theDoc, false );
-
- // incorporate the CASample file contents in theDoc
- returnErr = CAUtil_AddItemsFromDocFile (theDoc, &fileSpec, &dropMouse);
- }
-
- }
-
- SetPort( savePort );
-
- if (dataHandle)
- {
- DisposeHandle(dataHandle);
- dataHandle = NULL;
- }
-
- }
-
- #endif
-
-
- if (returnErr == noErr)
- {
- CARequestStandardFocusSet (theWindow);
- App_SetFrontDocWindow (theWindow);
- Doc_SetDirty(theDoc, true); // mark it changed
- }
-
- return returnErr;
- }
-
- //---------------------------------------------------------------------------
- //
- // Drag_DragTrackingHandler - This is the drag tracking handler for windows in the
- // Scrapbook application.
-
- pascal OSErr Drag_DragTrackingHandler(
- short message,
- WindowPtr theWindow,
- void *handlerRefCon,
- DragReference theDrag )
- {
- short offset;
- unsigned long attributes;
- RgnHandle theRgn;
- DocPtr theDoc;
- Point theMouse, localMouse;
-
- if ((message != dragTrackingEnterHandler) && !canAcceptItems)
- return noErr;
-
- // get the window theDoc.
- theDoc = (DocPtr)GetWRefCon( theWindow );
- GetDragAttributes( theDrag, &attributes );
-
- switch (message)
- {
- case dragTrackingEnterHandler:
-
- // We get called with this message the first time that a drag enters ANY
- // window in our application. Check to see if all of the drag items contain
- // a flavor we accept (which is any flavor), otherwise set canAcceptItems false.
- canAcceptItems = !theDoc->fileLocked && IsMyTypeAvailable(theDrag); // was true
- break;
-
- case dragTrackingEnterWindow:
- // We receive an EnterWindow message each time a drag enters one of our
- // application's windows. We initialize our global variables for tracking
- // the drag through the window.
- cursorInContent = false;
- break;
-
- case dragTrackingInWindow:
- // We receive InWindow messages as long as the mouse is in one of our windows
- // during a drag. We draw the window highlighting and blink the insertion caret
- // when we get these messages.
-
- GetDragMouse( theDrag, &theMouse, 0L );
- localMouse = theMouse;
- GlobalToLocal( &localMouse );
-
- // Show or hide the window highlighting when the mouse enters or leaves the
- // item frame in our window (we don't want to show the highlighting when
- // the mouse is over the window title bar or anywhere else).
-
- // if (attributes & dragHasLeftSenderWindow)
- // {
- // We assume that the drag manager sets our port before calling us
- // so we can set the background color to white. If we don't, the
- // ShowDragHilite and HideDragHilite don't seem to do anything.
- // $$$$$ RGBBackColor(&theDoc->whiteColor);
- if (PtInRect( localMouse, &theDoc->contentRect ))
- {
- if (!cursorInContent && (attributes & dragHasLeftSenderWindow))
- //if (!cursorInContent)
- {
- theRgn = NewRgn();
- RectRgn( theRgn, &theDoc->contentRect );
- ShowDragHilite( theDrag, theRgn, true );
- DisposeRgn( theRgn );
- }
- cursorInContent = true;
- }
- else
- {
- if (cursorInContent && (attributes & dragHasLeftSenderWindow))
- HideDragHilite( theDrag );
- cursorInContent = false;
- }
- // }
-
- offset = HitTest( theMouse, theDoc );
- break;
-
- case dragTrackingLeaveWindow:
- // Remove window highlighting, if showing.
- if (cursorInContent && (attributes & dragHasLeftSenderWindow))
- HideDragHilite( theDrag );
- break;
-
- case dragTrackingLeaveHandler:
- break;
-
- default:
- break;
- }
-
- return noErr;
- }
-
- pascal OSErr Drag_DragSendDataProc( FlavorType theType,
- void* refCon,
- ItemReference theItem,
- DragReference theDrag)
- {
-
- DocPtr theDoc = (DocPtr) refCon;
- OSErr err = noErr;
- FSSpec dropSpec;
- unsigned long secs;
- Str32 dateString;
- Str32 untitledName;
- Str32 tmpName;
- Str32 indexStr;
- FInfo ignore ;
- short index = 1;
- short count;
- ElemPtr elem;
- short selectedElemCount, selectedFrameCount, i;
- Boolean singleFrame = false;
-
- // Set if only a single frame is selection
- count = ElemColl_GetCount (theDoc->contentColl);
- for (i=1; i <= count; i++)
- {
- elem = ElemColl_GetNthElem (theDoc->contentColl, i);
-
- if (Elem_GetSelected (elem))
- {
- ++selectedElemCount;
- if (elem->elemType == kFrameElemType) ++selectedFrameCount;
- }
- }
-
- if ((selectedFrameCount == 1) && (selectedElemCount == 1)) singleFrame = true;
-
- switch (theType)
- {
-
-
- case kCAUserPromiseFlavor:
- case kCABentoFlavor:
-
- if (singleFrame)
- {
- // Let OpenDoc create the file
- err = badDragFlavorErr;
- break;
- }
-
- // Create a CASample file from the selection
- err = GetDropFSSpec(theDrag, &dropSpec);
-
- // Generate the file name: "SourceFileName 1"
- sCopyStr (theDoc->fileSpec.name, untitledName);
- sAppendStr ("\p ", untitledName);
-
- // Generate unique name
- //dropSpec.name[0] = 0;
- //GetDateTime(&secs);
- //IUDateString(secs,shortDate,(StringPtr)dateString);
- //sCopyStr ("\puntitled ", untitledName);
- //sAppendStr (dateString, untitledName);
- //sAppendStr ("\p ", untitledName);
-
- do
- {
-
- sCopyStr (untitledName, tmpName);
- NumToString (index, (StringPtr) indexStr);
- sAppendStr (indexStr, tmpName);
- sCopyStr ((StringPtr) tmpName, dropSpec.name);
- ++index;
-
- } while (FSpGetFInfo( &dropSpec, &ignore ) == noErr);
-
- CAUtil_CreateDocFileFromSelection (theDoc, &dropSpec);
-
- err = SetDragItemFlavorData(theDrag, theItem, theType, &dropSpec, sizeof(FSSpec), 0L);
-
- err = noErr;
-
- break;
-
-
- default:
-
- // The flavor may still be supplied internally, this
- // just means that we don't
- err = badDragFlavorErr;
- break;
-
-
- }
-
-
- return err;
-
- }
-
- //===========================================================================
- #pragma mark ' CASample Drag Routines
- //===========================================================================
-
- //---------------------------------------------------------------------------
- // Drag_DragItem
-
- Boolean Drag_DragItem(
- WindowPtr theWindow,
- EventRecord *theEvent )
- {
- OSErr theErr;
- RgnHandle dragRegion, tempRgn;
- PicHandle thePicture;
- DocPtr theDoc;
- Handle theScrap;
- Point saveOrigin;
- CADocumentRef dragDropDoc;
- GrafPtr savePort;
- CADropResult dropResult;
- Handle frameRefHandle;
- CASize dataLength;
- PromiseHFSFlavor thePromise;
- char OSTypeStr[5];
- CAISOStr typeStr;
- ElemListPtr selectionList;
-
- if (!WaitMouseMoved( theEvent->where ))
- return false;
-
- theDoc = (DocPtr)GetWRefCon( theWindow );
-
- // Get the ODDragDrop object
- dragDropDoc = CAGetDragDropDocument(0);
-
- // Set the document kind to our internal scrap format
- CASetDocumentKind(dragDropDoc, kCACASScrapTypeStr);
-
- // Create scrap data, including frame refs
- theScrap = Doc_CreateCAScrapFromSelection( theDoc, dragDropDoc, kCACloneCut );
-
- if (!theScrap)
- {
- // Drag is a single embedded frame
-
- // that easy
-
- }
- else
- {
-
- // Write data to dragdrop
- dataLength = GetHandleSize(theScrap);
-
- HLock( (Handle)theScrap );
- CAWrite(dragDropDoc, (char*) *theScrap, &dataLength);
- HUnlock( (Handle)theScrap );
-
- DisposHandle (theScrap);
-
- // Add kODHFSPromise for the finder, must support in dragsendproc
-
- /*
- // Additional representations
-
- typeStr = CAISOStrFromOSType (kPICTType);
- CASetDocumentKind(dragDropDoc, typeStr);
- DisposePtr (typeStr);
-
- thePicture = Doc_CreateSelectionPicture( theDoc );
-
- dataLength = GetHandleSize((Handle)thePicture);
-
- HLock((Handle) thePicture);
- CAWrite(dragDropDoc, (char*) thePicture, &dataLength);
- HUnlock((Handle) thePicture);
-
- KillPicture(thePicture);*/
-
-
- }
-
- // save the selection
- selectionList = ElemColl_GetCurrentSelection (theDoc->contentColl);
-
- GetPort( &savePort );
- SetPort( (GrafPtr)theWindow );
-
- // create the dragRegion in global coords
- dragRegion = NewRgn();
- Doc_CalcSelectionRgn(theDoc, dragRegion);
-
- GetOrigin( &saveOrigin );
- Doc_SetGrafOrigin( theDoc );
- RgnLocalToGlobal( dragRegion );
-
- SetOrigin( saveOrigin.h, saveOrigin.v );
-
- // Prepare the drag region.
- tempRgn = NewRgn();
- CopyRgn( dragRegion, tempRgn );
- InsetRgn( tempRgn, 1, 1 );
- DiffRgn( dragRegion, tempRgn, dragRegion );
- DisposeRgn( tempRgn );
-
- // Set the send data proc
- CASetDataSendProc (dragDropDoc, gDragSendProcUPP, (void *) theDoc);
-
- localDragInProgress = true;
-
- // Drag it
- dropResult = CAStartDrag( theDoc->partDocRef, theEvent, dragRegion );
-
- localDragInProgress = false;
-
- if (dropResult == kCADropFail)
- theErr = dragNotAcceptedErr;
- else
- theErr = noErr;
-
- DisposeRgn( dragRegion );
-
- CACloseDocument (dragDropDoc);
-
- if (dropResult == kCADropMove)
- {
- Doc_DeleteElements (theDoc, selectionList);
- ElemList_Free (selectionList);
- }
-
-
- // if it wasn't canceled by the user, then a drag occurred.
- return (theErr == noErr);
-
- }
-
- //---------------------------------------------------------------------------
- Boolean Drag_DragItemHasFlavor( DragReference theDrag,
- ItemReference itemID,
- OSType theType)
- {
- Boolean result = false;
- unsigned short count;
- short j;
- OSType itemType;
-
- CountDragItemFlavors(theDrag, itemID, &count);
- for (j = 1; j <= count; j++)
- {
- OSErr err = GetFlavorType(theDrag, itemID, j, &itemType);
- if ( err != noErr )
- break;
- if (itemType == theType)
- {
- result = true;
- break;
- }
- }
-
- return result;
- }
-
-
- Handle Drag_GetFlavorData ( DragReference theDrag,
- ItemReference theItem,
- OSType theType)
- {
- Handle dataHandle;
- OSErr theErr = noErr;
- long dataSize = 0;
-
- // get the flavor data size
- theErr = GetFlavorDataSize( theDrag, theItem, theType, &dataSize );
- if (theErr != noErr)
- {
- DEBUGSTR("\p Drag_GetFlavorData: error after GetFlavorDataSize");
- return NULL;
- }
-
- // allocate the space
- dataHandle = NewHandle( dataSize );
- if (dataHandle == nil)
- {
- DEBUGSTR( "\p Drag_GetFlavorData: NewHandle failed" );
- return NULL;
- }
-
- // Get the actual flavor data.
- HLock( dataHandle);
- theErr = GetFlavorData(theDrag, theItem, theType, *dataHandle, &dataSize, 0L );
- HUnlock( dataHandle );
-
- if (theErr != noErr)
- {
- DEBUGSTR( "\p MyReceiveDropHandler: error after GetFlavorData" );
- DisposeHandle( dataHandle );
- return NULL;
- }
-
- return (dataHandle);
-
- }
-
-
- //---------------------------------------------------------------------------
- // Returns true if the given dropLocation AEDesc is a descriptor of the Finder's Trash.
-
- static Boolean DropLocationIsFinderTrash(
- AEDesc *dropLocation )
- {
- OSErr theErr;
- AEDesc dropSpec;
- FSSpec *theSpec;
- CInfoPBRec thePB;
- short trashVRefNum;
- long trashDirID;
-
- // Coerce the dropLocation descriptor to an FSSpec. If there's no dropLocation or
- // it can't be coerced into an FSSpec, then it couldn't have been the Trash.
- theErr = AECoerceDesc( dropLocation, typeFSS, &dropSpec );
- if ((dropLocation->descriptorType != typeNull) && (theErr == noErr))
- {
- HLock( dropSpec.dataHandle );
- theSpec = (FSSpec*)*dropSpec.dataHandle;
-
- /* Get the directory ID of the given dropLocation object. */
- thePB.dirInfo.ioCompletion = 0L;
- thePB.dirInfo.ioNamePtr = (StringPtr) &theSpec->name;
- thePB.dirInfo.ioVRefNum = theSpec->vRefNum;
- thePB.dirInfo.ioFDirIndex = 0;
- thePB.dirInfo.ioDrDirID = theSpec->parID;
-
- theErr = PBGetCatInfo( &thePB, false );
-
- HUnlock(dropSpec.dataHandle);
- AEDisposeDesc(&dropSpec);
-
- if (theErr != noErr)
- return false;
-
- // If the result is not a directory, it must not be the Trash.
- if (!(thePB.dirInfo.ioFlAttrib & (1 << 4)))
- return false;
-
- // Get information about the Trash folder.
- theErr = FindFolder(
- theSpec->vRefNum, kTrashFolderType, kCreateFolder,
- &trashVRefNum, &trashDirID );
- if (theErr != noErr)
- return false;
-
- // If the directory ID of the dropLocation object is the same as the directory ID
- // returned by FindFolder, then the drop must have occurred into the Trash.
- if (thePB.dirInfo.ioDrDirID == trashDirID)
- return true;
- }
-
- return false;
- }
-
- //---------------------------------------------------------------------------
- // Given a point in global coordinates, HitTest returns 1 if the point is inside
- // the content area of the window. If the point is not inside the window,
- // HitTest return 0. Note: this should return the insertion item number. if
- // the Scrapbook were modified to show more than one item at a time.
-
- static short HitTest(
- Point theLoc,
- DocPtr theDoc )
- {
- #if 1
- Point localMouse;
-
- localMouse = theLoc;
- GlobalToLocal( &localMouse );
-
- if (PtInRect( localMouse, &theDoc->contentRect ))
- return 1;
- else
- return 0;
- #else
- return 1;
- #endif
- }
-
- #if 0
- //---------------------------------------------------------------------------
- // given a fileSpec, get the first resource of theType from the resource file and
- // return it in the handle after detaching if from the resource file.
-
- static OSErr GetResFromFile(
- FSSpec *fileSpec,
- Handle *h,
- OSType theType )
- {
- OSErr theErr;
- short theFileNum, savedResFile;
- short theCount;
-
- *h = nil;
- theErr = noErr;
- savedResFile = CurResFile();
-
- theFileNum = FSpOpenResFile( fileSpec, fsRdPerm );
- theErr = ResError();
- if (theErr != noErr)
- goto closeout;
-
- theCount = Count1Resources( theType );
- if (theCount < 1)
- {
- theErr = resNotFound;
- goto closeout;
- }
-
- *h = Get1IndResource( theType, 1 ); // get the first resource of theType
- DetachResource( *h );
-
- closeout:
- if (theFileNum > 0)
- CloseResFile( theFileNum );
- if (savedResFile >= 0)
- UseResFile( savedResFile );
-
- return theErr;
- }
- #endif
-
- //---------------------------------------------------------------------------
- // given a fileSpec, return the date from the data fork of the file starting
- // at offset and continuing to maxLength or the end of the file.
-
- static OSErr GetDataFromFile(
- FSSpec *fileSpec,
- Handle *h,
- long offset,
- long maxLength )
- {
- OSErr theErr;
- long fileLength;
- short theFileNum;
-
- *h = nil;
- theErr = noErr;
- theFileNum = 0;
-
- theErr = FSpOpenDF( fileSpec, fsRdPerm, &theFileNum );
- if (theErr != noErr)
- goto closeout;
-
- theErr = GetEOF( theFileNum, &fileLength );
- if (theErr != noErr)
- goto closeout;
-
- if (fileLength < offset)
- {
- theErr = eofErr;
- goto closeout;
- }
-
- fileLength -= offset;
- if (fileLength > maxLength)
- fileLength = maxLength;
-
- *h = NewHandle (fileLength);
- theErr = MemError();
- if (theErr != noErr)
- goto closeout;
-
- theErr = SetFPos( theFileNum, fsFromStart, offset ); // skip any header
- if (theErr != noErr)
- goto closeout;
-
- theErr = FSRead( theFileNum, &fileLength, **h );
-
- closeout:
- if (theFileNum > 0)
- FSClose( theFileNum );
-
- return theErr;
- }
-
- //---------------------------------------------------------------------------
- // loop through all the drag items and make sure there is at least one flavor
- // (in each item) that we can accept.
-
- static Boolean IsMyTypeAvailable(
- DragReference theDrag )
- {
- OSErr theErr;
- unsigned short numItems, index;
-
-
- theErr = CountDragItems( theDrag, &numItems );
- if ((theErr != noErr) || (numItems <= 0))
- return false;
-
- // Loop through all of the drag items contained in this drag.
- for (index = 1; index <= numItems; index++)
- {
- ItemReference theItem;
- unsigned short flavorIndex;
- FlavorType theType;
- Size dataSize;
- FlavorFlags theFlags;
- HFSFlavor theHFSFlavor;
-
- // Get the item's reference number, so we can refer to it.
- theErr = GetDragItemReferenceNumber( theDrag, index, &theItem );
- if (theErr)
- break;
-
- if (Drag_DragItemHasFlavor (theDrag, theItem, kCAPromiseFlavor))
- {
- // Can always embed the drag contents
- return true;
- }
- else if (Drag_DragItemHasFlavor (theDrag, theItem, kCACASScrapType))
- {
- return true;
- }
- else if (Drag_DragItemHasFlavor (theDrag, theItem, flavorTypeHFS))
- {
- dataSize = sizeof(theHFSFlavor);
- theErr = GetFlavorData( theDrag, theItem, flavorTypeHFS, &theHFSFlavor, &dataSize, 0L );
- if (theErr != noErr)
- {
- DEBUGSTR( "\p IsMyTypeAvailable: error after GetFlavorData" );
- continue; // go on to the next flavor.
- }
-
- // if it's a Finder clipping…
- if (theHFSFlavor.fileCreator == 'drag')
- continue; // go on to the next flavor. There should be another flavor we like.
-
- // if it's a PICT, we'll take it.
- if (theHFSFlavor.fileType == kPICTType)
- return true;
-
- if (theHFSFlavor.fileCreator == kODShellSignature)
- return true;
-
- if (theHFSFlavor.fileCreator == kOurFileCreator)
- return true;
-
- }
-
- }
-
- return false; // didn't find any suitable flavors.
- }
-
- //---------------------------------------------------------------------------
- static OSErr GetDropFSSpec(DragReference theDrag, FSSpec *dropFSSpec)
- {
- AEDesc dropDescriptor;
- CInfoPBRec getInfoPB;
-
- OSErr result = GetDropLocation(theDrag, &dropDescriptor);
- if (result != noErr || dropDescriptor.descriptorType == typeNull)
- result = fnfErr; // Can't create a file unless we know where it goes!
- else
- {
- AEDesc fssDescriptor;
- result = AECoerceDesc(&dropDescriptor, typeFSS, &fssDescriptor);
- AEDisposeDesc(&dropDescriptor);
- if (result == noErr) {
- BlockMove(*fssDescriptor.dataHandle, dropFSSpec, sizeof(FSSpec));
- AEDisposeDesc(&fssDescriptor);
-
- // Use PBGetCatInfo to get the directoryID of the target directory.
- getInfoPB.dirInfo.ioCompletion = 0L;
- getInfoPB.dirInfo.ioNamePtr = (StringPtr) &(dropFSSpec->name);
- getInfoPB.dirInfo.ioVRefNum = dropFSSpec->vRefNum;
- getInfoPB.dirInfo.ioFDirIndex = 0;
- getInfoPB.dirInfo.ioDrDirID = dropFSSpec->parID;
- result = PBGetCatInfo(&getInfoPB, false);
- if (result == noErr)
- {
- dropFSSpec->parID = getInfoPB.dirInfo.ioDrDirID;
- dropFSSpec->name[0] = 0;
- }
- }
- }
-
- return result;
- }
-
- //===========================================================================
- #pragma mark ' Pre-CAList Drag Methods
- //===========================================================================
-
-
- #ifdef USE_CALIB
- //---------------------------------------------------------------------------
- //
- // DragItem - Drag the selected items from the window. Return true if a
- // drag occurs or false if not.
-
- Boolean DragItem(
- WindowPtr theWindow,
- EventRecord *theEvent )
- {
- #ifdef OLDWAY
- OSErr theErr;
- RgnHandle dragRegion, tempRgn;
- DragReference theDrag;
- AEDesc dropLocation;
- DragAttributes attributes;
- short mouseDownModifiers,
- mouseUpModifiers,
- copyItem;
- PicHandle thePicture;
- DocPtr theDoc;
- Handle theScrap;
- Point saveOrigin;
- CADocumentRef dragDropDoc;
- ItemReference item = 1;
- GrafPtr savePort;
- CADropResult dropResult;
-
- // Wait for the mouse to move or the mouse button to be released. If the mouse button was
- // released before the mouse moves, return false. Returning false from DragItem means that
- // a drag operation did not occur.
- if (!WaitMouseMoved( theEvent->where ))
- return false; // indicate that a drag did not occur.
-
- theDoc = (DocPtr)GetWRefCon( theWindow );
-
- // create the drag ($$$$$ ignore any errors?).
- NewDrag( &theDrag );
-
- #ifdef USE_CALIB
- {
- Handle frameRefHandle;
-
- // Get the ODDragDrop object
-
- dragDropDoc = CAGetDragDropDocument(&item, kCACloneCopy);
- CASetDocumentKind(dragDropDoc, kCACASScrapTypeStr);
-
- // Clone frames
- //frameRefHandle = Doc_CloneSelectedFrames (theDoc, dragDropDoc);
-
- // Copy our own format "kCACASScrapType" data to the scrap
- theScrap = Doc_CreateCAScrapFromSelection( theDoc, dragDropDoc, kCACloneCut );
-
- DisposHandle (frameRefHandle);
-
- // Call CACloseDocument after the drag is complete
-
- }
- #else
-
- // Add our own format first
- theScrap = Doc_CreateScrapFromSelection(theDoc);
-
- #endif
-
- if (theScrap)
- {
-
- HLock( (Handle)theScrap );
-
- #ifdef USE_CALIB
-
- AddDragItemFlavor(
- theDrag, item, kCACASScrapType, (Ptr) *theScrap,
- GetHandleSize( (Handle)theScrap ), 0 );
-
- #else
-
- AddDragItemFlavor(
- theDrag, 1, kCASScrapType, (Ptr) *theScrap,
- GetHandleSize( (Handle)theScrap ), 0 );
-
- #endif
- HUnlock( (Handle)theScrap );
-
- // get rid of the picture.
- DisposHandle (theScrap);
- }
- #ifdef USE_CALIB
-
- else
- {
-
- // Single embedded frame
-
- //AddDragItemFlavor(
- // theDrag, 1, kODBentoFlavor, 0, 0, 0 );
-
- AddDragItemFlavor(
- theDrag, item, kCABentoFlavor, 0, 0, 0 );
-
- }
-
- #endif
-
-
- /*
- // create a picture from the selected items.
- thePicture = Doc_CreateSelectionPicture( theDoc );
- if (thePicture == nil)
- return(false);
-
- // add our picture to the drag ($$$$$ ignore any errors?).
- HLock((Handle) thePicture);
- AddDragItemFlavor(
- theDrag, item, kPICTType, (Ptr)*thePicture,
- GetHandleSize( (Handle)thePicture), 0 );
- HUnlock((Handle) thePicture);
-
- // get rid of the picture.
- KillPicture(thePicture);*/
-
- GetPort( &savePort );
- SetPort( (GrafPtr)theWindow );
-
-
- // create the dragRegion from the selection and offset it into global coordinates.
- dragRegion = NewRgn();
- Doc_CalcSelectionRgn(theDoc, dragRegion);
-
- GetOrigin( &saveOrigin );
- Doc_SetGrafOrigin( theDoc );
-
- RgnLocalToGlobal( dragRegion );
-
- SetOrigin( saveOrigin.h, saveOrigin.v );
-
- // Set the item's bounding rectangle in global coordinates.
- //SetDragItemBounds( theDrag, item, &(**dragRegion).rgnBBox );
-
- // Prepare the drag region.
- tempRgn = NewRgn();
- CopyRgn (dragRegion, tempRgn );
- InsetRgn (tempRgn, 1, 1 );
- DiffRgn (dragRegion, tempRgn, dragRegion );
- DisposeRgn (tempRgn);
-
- SetPort(savePort);
-
- CASetDataSendProc (theDrag, gDragSendProcUPP, (void *) NULL);
-
- // Drag the item. TrackDrag will return userCanceledErr if the drop zoomed-back
- // for any reason.
- //theErr = TrackDrag( theDrag, theEvent, dragRegion );
- dropResult = CAStartDrag( theDoc->partDocRef, theDrag, theEvent, dragRegion );
-
- theErr = noErr;
-
- // Dispose of the drag.
- DisposeDrag( theDrag );
- DisposeRgn( dragRegion );
-
- #ifdef USE_CALIB
- CACloseDocument (dragDropDoc);
- #endif
-
- if (dropResult == kCADropMove)
- {
- //Doc_DeleteSelection (theDoc);
- }
-
-
- if ((theErr != noErr) && (theErr != userCanceledErr)) // if an error occured
- return false; // indicate that a drag did not occur.
-
- // Check to see if the drop occurred in the Finder's Trash. If the drop occurred
- // in the Finder's Trash and a copy operation wasn't specified, delete the
- // source selection. Note that we can continue to get the attributes, drop location
- // modifiers, etc. of the drag until we dispose of it using DisposeDrag.
-
-
- #if 0 // The DropLocationIsFinderTrash call causes a crash on AECoerceDesc
- GetDragAttributes( theDrag, &attributes );
- if (!(attributes & dragInsideSenderApplication))
- {
- GetDropLocation( theDrag, &dropLocation );
-
- GetDragModifiers( theDrag, 0L, &mouseDownModifiers, &mouseUpModifiers );
- copyItem = (mouseDownModifiers | mouseUpModifiers) & optionKey;
-
- if (!copyItem && DropLocationIsFinderTrash(&dropLocation) && !theDoc->fileLocked)
- Doc_ClearMenu( theDoc );
-
- AEDisposeDesc( &dropLocation );
- }
- #endif
-
- // if it wasn't canceled by the user, then a drag occurred.
- return (theErr != userCanceledErr);
-
- #endif
- }
-
-
- #endif
-
-
-
-
-
- #ifndef USE_CALIB
- //---------------------------------------------------------------------------
- //
- // Drag_DragReceiveHandler - Called by the Drag Manager when a drop occurs over our window.
-
- pascal OSErr Drag_DragReceiveHandler(
- WindowPtr theWindow,
- void *handlerRefCon,
- DragReference theDrag )
- {
- OSErr theErr;
- unsigned short numItems, index;
- DragAttributes attributes;
- short mouseDownModifiers, mouseUpModifiers;
- GrafPtr savePort;
- DocPtr theDoc;
- Boolean skipPict = false;
-
- // if we can't accept the item flavors or the cursor isn't over the item frame,
- // don't accept the drag.
- if (!canAcceptItems || !cursorInContent)
- return dragNotAcceptedErr;
-
- theDoc = (DocPtr)GetWRefCon( theWindow );
-
- GetPort( &savePort );
- SetPort( (GrafPtr)theWindow );
-
- theErr = GetDragAttributes( theDrag, &attributes );
-
- // are we moving the items within our own window?
- if (attributes & dragInsideSenderWindow)
- {
- Point startPt, endPt;
-
- // This is where we move the items.
- theErr = GetDragOrigin( theDrag, &startPt );
- theErr = GetDragMouse( theDrag, &endPt, nil );
-
- Doc_MoveSelection( theDoc, endPt.h - startPt.h, endPt.v - startPt.v );
-
- SetPort( savePort );
- return noErr;
- }
-
- theErr = GetDragModifiers( theDrag, 0L, &mouseDownModifiers, &mouseUpModifiers );
- if (theErr != noErr)
- {
- SetPort( savePort );
- return theErr;
- }
-
- theErr = CountDragItems( theDrag, &numItems );
- if (theErr != noErr)
- {
- SetPort( savePort );
- return theErr;
- }
-
- if (numItems <= 0) // if there is nothing to receive…
- {
- SetPort( savePort );
- theErr = dragNotAcceptedErr;
- return theErr;
- }
-
- // turn off the hiliting if needed
- if (attributes & dragHasLeftSenderWindow)
- HideDragHilite( theDrag );
-
- // page = GetCtlValue(theDoc->scrollBar); /* get current page */
-
- // Loop through all of the drag items contained in this drag and add an item for each.
- for (index = 1; index <= numItems; index++)
- {
- ItemReference theItem;
- unsigned short numFlavors;
- unsigned short flavorIndex;
- FlavorType theType;
- Size dataSize;
- FlavorFlags theFlags;
-
- DebugStr ("\pd2");
-
- // Get the item's reference number, so we can refer to it.
- // count the number of item flavors.
- theErr = GetDragItemReferenceNumber( theDrag, index, &theItem );
- theErr = CountDragItemFlavors( theDrag, theItem, &numFlavors );
-
- // loop through all the drag item flavors and add them to the new item.
- for (flavorIndex = 1; flavorIndex <= numFlavors; flavorIndex++)
- {
- Handle h;
-
- // get the flavor type
- theErr = GetFlavorType( theDrag, theItem, flavorIndex, &theType );
- if (theErr != noErr)
- {
- DEBUGSTR( "\p MyReceiveDropHandler: error after GetFlavorType" );
- continue;
- }
-
- if ((theType == flavorTypePromiseHFS) // ignore old Sys 7 Pro Finder 'phfs' promised flavor. Tip from PixelPaint dudes.
- || (theType == flavorTypeDirectory) // ignore OCE types 'diry'. Tip from Eric Hanig at Oracle.
- || (theType == 'movr')) // ignore Finder movr flavor since it's empty
- continue;
-
- // Get the flavor flags
- theErr = GetFlavorFlags( theDrag, theItem, theType, &theFlags );
- if (theErr != noErr)
- {
- DEBUGSTR("\p MyReceiveDropHandler: error after GetFlavorFlags");
- continue;
- }
-
- if ((theFlags & flavorSystemTranslated) // don't take any translation manager flavors.
- || (theFlags & flavorNotSaved) // don't take any flavors that will become stale.
- || (theFlags & flavorSenderOnly)) // don't take any flavors that are for the sender only
- continue;
-
- // get the flavor data size
- theErr = GetFlavorDataSize( theDrag, theItem, theType, &dataSize );
- if (theErr != noErr)
- {
- DEBUGSTR("\p MyReceiveDropHandler: error after GetFlavorDataSize");
- continue;
- }
-
- // if it's got no data, skip it.
- if (dataSize <= 0L)
- continue;
-
- // allocate the space
- h = NewHandle( dataSize );
- if (h == nil)
- {
- DEBUGSTR( "\p MyReceiveDropHandler: NewHandle failed" );
- continue;
- }
-
- // Get the actual flavor data.
- HLock( h);
- theErr = GetFlavorData(theDrag, theItem, theType, *h, &dataSize, 0L );
- HUnlock( h );
- if (theErr != noErr)
- {
- DEBUGSTR( "\p MyReceiveDropHandler: error after GetFlavorData" );
- DisposeHandle( h ); /* clean up */
- continue;
- }
- DebugStr ("\pd3");
-
- if (theType == kCACASScrapType)
- {
- Point dropPoint;
- Rect itemBounds;
- Rect docBounds;
- GrafPtr savePort;
- CADocumentRef dragDropDoc;
-
- GetPort( &savePort );
- SetPort( (GrafPtr)Doc_GetWindow( theDoc ) );
-
- // Calc our docs window rect in global coords.
- docBounds = theWindow->portRect;
-
- GetDragItemBounds( theDrag, theItem, &itemBounds );
-
- dropPoint.v = itemBounds.top - docBounds.top;
- dropPoint.h = itemBounds.left - docBounds.left;
-
- GlobalToLocal( &dropPoint );
-
- SetPort( savePort );
-
-
- dragDropDoc = CAGetDragDropDocument(kCACloneDropCopy);
- Doc_AddItemsFromCAScrap( theDoc, h, &dropPoint, dragDropDoc );
-
- //Doc_AddItemsFromScrap (theDoc, h, dropPoint);
- DisposeHandle( h );
- skipPict = true;
- continue;
- }
-
- // if it's a file/folder (hfs ) from the Finder check it's type
- // and see if we can read it into a handle
- else if (theType == flavorTypeHFS)
- {
- HFSFlavor theHFSFlavor;
-
- // save the flavor
- BlockMoveData( *h, &theHFSFlavor, (long)sizeof(HFSFlavor) );
-
- DisposeHandle( h ); // throw away the handle, we'll get a new one.
- h = nil;
-
- if (theHFSFlavor.fileType == kPICTType) // PICT file?
- {
- theType = kPICTType;
-
- // open the data fork and read the pict out of it.
- theErr = GetDataFromFile(&theHFSFlavor.fileSpec, &h, 512, 0x7FFFFFFF);
- }
- else if (theHFSFlavor.fileCreator == 'drag') // CREATOR is Finder clipping file?
- {
- // ignore it since we'll get the clipping flavors also.
- theErr = noErr;
- continue;
- }
- else
- {
- // indicate we don't have anything.
- theErr = resNotFound;
- }
- }
-
- else if ((theType == kPICTType) && skipPict)
- {
- DisposeHandle( h );
- continue;
- }
- // $$$$$ add the PICT (h) to our list at the correct point.
- if (theErr == noErr)
- {
- Point dropPoint;
- Rect itemBounds;
- Rect docBounds;
-
- // Calc our docs window rect in global coords.
- docBounds.top = theWindow->portRect.top;
- docBounds.left = theWindow->portRect.left;
- docBounds.bottom = theWindow->portRect.bottom;
- docBounds.right = theWindow->portRect.right;
-
- GetDragItemBounds (theDrag, theItem, &itemBounds);
-
- dropPoint.v = itemBounds.top - docBounds.top;
- dropPoint.h = itemBounds.left - docBounds.left;
-
- Doc_AddItemPict( theDoc, (PicHandle)h, dropPoint );
- DisposeHandle( h ); // h was allocated in GetDataFromFile
- // AddResource(h, theType, resID, "\p");
- // theErr = ResError();
- }
- }
- }
- DebugStr ("\pd4");
-
- Doc_SetDirty(theDoc, true); // mark it changed
-
- // $$$$$ if nothing was dropped, return an error (dragNotAcceptedErr)
- return noErr;
- }
- #endif